package CSDN_Blog_Util;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.stream.Stream;

/**
 * 无后缀文件+纯数字文件名.md 重命名工具：提取第一行作为标题并添加.md后缀
 */
public class FileRenameToMd {

    // ===================== 配置参数（修改这里即可）=====================
    /** 需要处理的根目录（绝对路径） */
    private static final String ROOT_DIR = "D:\\project\\gitee\\my-books\\扣子自动生成书籍"; // 你的目录路径
    /** 是否处理子目录中的文件（true=处理子目录，false=仅当前目录） */
    private static final boolean INCLUDE_SUB_DIR = true;
    /** 文件名非法字符替换为该字符（默认用下划线） */
    private static final String REPLACE_CHAR = "_";
    // =================================================================

    public static void main(String[] args) {
        try {
            Path rootPath = Paths.get(ROOT_DIR);
            // 验证目录是否存在
            if (!Files.exists(rootPath) || !Files.isDirectory(rootPath)) {
                throw new IllegalArgumentException("目录不存在或不是有效目录：" + ROOT_DIR);
            }

            // 遍历目录（深度：子目录=Integer.MAX_VALUE，当前目录=1）
            int maxDepth = INCLUDE_SUB_DIR ? Integer.MAX_VALUE : 1;
            try (Stream<Path> pathStream = Files.walk(rootPath, maxDepth)) {
                pathStream
                        .filter(Files::isRegularFile) // 只处理文件
                        .filter(FileRenameToMd::needRename) // 核心过滤：需要重命名的文件（无后缀 或 纯数字.md）
                        .forEach(path -> {
                            try {
                                processFile(path); // 处理单个文件
                            } catch (Exception e) {
                                System.err.println("❌ 处理失败（" + e.getMessage() + "）：" + path.toAbsolutePath());
                            }
                        });
            }

            System.out.println("\n🎉 所有文件处理完成！");

        } catch (Exception e) {
            System.err.println("❌ 程序异常终止：" + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 判断文件是否需要重命名：
     * 1. 无后缀文件（文件名不含.）
     * 2. 文件名仅含数字 + .md后缀（如1.md、1234.md）
     */
    private static boolean needRename(Path path) {
        String fileName = path.getFileName().toString();

        // 情况1：无后缀文件（不含.）
        if (!fileName.contains(".")) {
            return true;
        }

        // 情况2：拆分文件名和后缀，判断是否是“纯数字.md”
        String[] nameParts = splitFileName(fileName);
        String prefix = nameParts[0]; // 文件名前缀（.前面的部分）
        String suffix = nameParts[1]; // 文件后缀（.后面的部分）

        // 后缀是md，且前缀仅由数字组成（空前缀排除，如“.md”这种无效文件名）
        return "md".equalsIgnoreCase(suffix) && !prefix.isEmpty() && prefix.matches("^\\d+$");
    }

    /**
     * 拆分文件名的“前缀”和“后缀”（如“abc.md”→[abc, md]，“123”→[123, null]，“.gitignore”→[, gitignore]）
     */
    private static String[] splitFileName(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex == -1) {
            return new String[]{fileName, null}; // 无后缀
        }
        // 有后缀：拆分前缀和后缀
        String prefix = fileName.substring(0, lastDotIndex);
        String suffix = fileName.substring(lastDotIndex + 1);
        return new String[]{prefix, suffix};
    }

    /**
     * 处理单个文件：提取第一行作为标题并添加.md后缀
     */
    private static void processFile(Path filePath) throws IOException {
        // 1. 读取文件第一行内容（作为标题源）
        String firstLine = readFirstLine(filePath);
        if (firstLine == null || firstLine.trim().isEmpty()) {
            throw new IOException("文件第一行为空，无法作为标题");
        }

        // 2. 处理标题：去除开头的"## "（如果有），并trim
        String title = firstLine.trim();
        if (title.startsWith("## ")) {
            title = title.substring(3).trim(); // 去除"## "后再trim
        }

        // 3. 过滤文件名中的非法字符（Windows/Linux通用非法字符）
        String validFileName = filterInvalidChars(title);
        if (validFileName.isEmpty()) {
            throw new IOException("处理后标题为空，无法作为文件名");
        }

        // 4. 生成目标文件名（添加.md后缀）
        String targetFileName = validFileName + ".md";
        Path targetPath = filePath.getParent().resolve(targetFileName);

        // 5. 处理文件名冲突（如果已存在则添加序号，如"标题.md" → "标题_1.md"）
        targetPath = resolveDuplicatePath(targetPath);

        // 6. 执行重命名（覆盖已存在的文件，避免冲突）
        Files.move(filePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
        System.out.println("✅ 重命名成功：" + filePath.getFileName() + " → " + targetPath.getFileName());
    }

    /**
     * 读取文件第一行内容（UTF-8编码）
     */
    private static String readFirstLine(Path path) throws IOException {
        try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
            return reader.readLine(); // 读取第一行（null表示文件为空）
        }
    }

    /**
     * 过滤文件名中的非法字符（替换为REPLACE_CHAR）
     * 非法字符包括：\/:*?"<>|
     */
    private static String filterInvalidChars(String fileName) {
        // 正则匹配所有非法字符，替换为指定字符
        return fileName.replaceAll("[\\\\/:*?\"<>|]", REPLACE_CHAR);
    }

    /**
     * 处理文件名冲突：如果目标路径已存在，添加序号（如"a.md" → "a_1.md" → "a_2.md"）
     */
    private static Path resolveDuplicatePath(Path targetPath) {
        if (!Files.exists(targetPath)) {
            return targetPath; // 不存在，直接返回
        }

        // 分离文件名和扩展名（固定是.md）
        String originalName = targetPath.getFileName().toString();
        String baseName = originalName.substring(0, originalName.length() - 3); // 去除.md
        Path parentDir = targetPath.getParent();

        // 循环查找不冲突的文件名（从1开始累加序号）
        int index = 1;
        while (true) {
            String newName = baseName + "_" + index + ".md";
            Path newPath = parentDir.resolve(newName);
            if (!Files.exists(newPath)) {
                return newPath;
            }
            index++;
        }
    }
}